/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package compevol;

import java.util.Collections;
import java.util.Vector;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.renderer.category.ScatterRenderer;

/**
 * Selecao por roleta, faz com que a cada rodada seja escolhido um novo individuo 
 * da populacao sem repeticao.
 * @author Alessandro
 */
public class SelecaoRoleta implements Selecao {

    // Elementos selecionados devem ser retirados do vetor de individuos da populacao inicial
    public Vector<Individuo> seleciona(Populacao inicial, int numeroPais) {

        // Os pais que serao selecionados para a proxima reproducao
        Vector<Individuo> pais = new Vector<Individuo>();
        // O somatorio do fitness da populacao, usado no calculo da roleta
        double sumFitnessPopulacional = inicial.fitnessPopulacional();
        // Guarda o resultado sorteado pela roleta aleatoria
        double sorteioRoleta;
        // Guarda o acumulado do fitnesse relativo
        double sumFitnessRelativo = 0;
        // Guarda o indice do individuo ganhador da roleta
        int vencedor;
        // Ordena os individuos em ordem crescente de fitness
        Collections.sort(inicial.individuos);
        // Tamanho da populacao que varia conforme selecionamos elementos dela
        int tamanho;
        // Guarda o indice do individuo selecionado a cada iteracao
        int selecionado;

        for (int i = 0; i < numeroPais; i++) {
            // Gira a roleta buscando um valor entre 0 e 1
            sorteioRoleta = Math.random();

            // Descobre o tamanho atual da populacao
            tamanho = inicial.individuos.size();

            // Inicialmente nao temos um vencedor
            vencedor = -1;

            // Ate selecionar todos os pais varre a populacao
            selecionado = 0;
            do {
                // Incrementa o fitness relativo, ficaremos com o individuo que tiver a maior soma
                // maior que o sorteio.
                sumFitnessRelativo += inicial.config.funcao.avalia(inicial.individuos.get(selecionado)) / sumFitnessPopulacional;
                if(sumFitnessRelativo > sorteioRoleta)
                    vencedor = selecionado;

                selecionado++;
            }
            while( (vencedor == -1) && (selecionado < tamanho) );

            // Nesse caso, passamos por toda a populacao, e nao encontramos o melhor,
            // pode acontecer se der algum problema em relacao a probabilidade nao fechar exata
            // nesse caso pegamos o ultimo elemento, que seria o com melhor aptidao, pois ja 
            // ordenamos a lista.
            if(vencedor == -1)
                vencedor = tamanho - 1;

            // Insere melhor individo no vetor de pais:
            pais.add(inicial.individuos.get(vencedor));

            // Remove individuo da populacao para nao ser escolhido denovo:
            inicial.individuos.remove(vencedor);

            // Decrementa o tamanho ja que reduziu a populacao
//            tamanho--;
        }

        return pais;
    }
    @Override
    public String toString() {
        return "Roleta";
    }
}
